<template>
<div>
<!--      <el-button @click="getLocationByAmap">高德定位</el-button>-->
  <AMapView :updateMap="updateMap" :updateCoordsy="updateCoordsy" :can-change-layer="true"></AMapView>


<!--      <div id="map">
        <div id="container"></div>
        <div class="mapinfo">
        </div>
      </div>-->
    <div>
      <SpeedGauge class="speedSetting" :speed=speed style="height: 150px;width: 150px"></SpeedGauge>
      <div class="speedSetting info">
<!--        <el-button @click="getLocationByJs">js定位</el-button>-->
        <el-button :disabled="this.uploadDate.isStartWatch" @click="startPath" circle icon="el-icon-video-play" type="primary" size="medium"></el-button>
        <el-button :disabled="!this.uploadDate.isStartWatch" @click="pausePath" circle icon="el-icon-video-pause" type="info" size="medium"></el-button>
        <el-button :disabled="!(this.uploadDate.positions.length>1)" @click="stopPath" circle icon="el-icon-finished" type="success" size="medium"></el-button>
        <el-button @click="export2JSON" v-if="!this.uploadDate.isStartWatch&&this.uploadDate.positions.length!==0">导出</el-button>
        <div class="info">跟踪:<el-switch v-model="uploadDate.followPosition"/></div>
        <div class="info">模拟:<el-switch v-model="simulationData.startPositionSimulation" :disabled="(this.uploadDate.positions.length>1)"/></div>
        <span class="info" id="currentPosition">{{this.currentPositionText}}</span>
        <span class="info">定位精度:{{accuracy}}米</span>
      </div>
    </div>
</div>
</template>

<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import {reqPostPolyline} from "@/api/polyline"

import {requestGetData, requestIsSuccess} from "@/api/request";
import {convert_gps84_To_Gcj02, MyMap, MyMapOpt} from "@/class/map/myMapOpt";
import SpeedGauge from "@/views/map/SpeedGauge.vue";
import {successMessage} from "@/utils/message";
import {count} from "echarts/lib/component/dataZoom/history";
import {MapData} from "@/class/map/MapData";
import {Polyline, PolylineData} from "@/class/map/Polyline";
import {PolygonData} from "@/class/map/Polygon";
import {simulationPositions} from "@/utils/data";
import AMapView from "@/views/map/AMapView.vue";
import img from "../../../public/direction.svg";
import {reqPutAddPath,reqPostTrack} from "@/api/track";
import {Track, TrackData} from "@/class/map/Track";
import {getColorBySpeed} from "@/utils/map_color";
let map
let geolocation
let googleTitleLayer
let amapTitleLayer
//当前位置点名称
const currentPositionName="currentPosition";
//上传坐标值的周期，单位ms
const uploadPositionsTime=5 * 1000
export default {
  name: "MapTravel",
  components:{
    SpeedGauge,AMapView
  },
  computed:{
    currentPositionText(){
      const c = 3;
      let result;
      if(typeof(this.currentPositionOpt.position)!=="undefined") {
        result = "经度:" + this.currentPositionOpt.position[0].toFixed(c) + " " +
            "纬度:" + this.currentPositionOpt.position[1].toFixed(c)
      }
      else{
        result = "未开启"
      }
      return result
    }

  },
  methods:{
    updateCoordsy(coordsy){

    },
    updateMap(map){
      this.map=map
      let img=require("/public/direction.svg")
      this.currentPositionOpt.icon=new AMap["Icon"]({
        image: img,
        imageSize:[36,36]
      })
      if (navigator.geolocation){
        navigator.geolocation.getCurrentPosition(position => {
          let {longitude, latitude}=position.coords
          this.map.setCenter([longitude,latitude])
        },(e)=>{
          this.warningMessage("定位失败")
        },{
          enableHighAccuracy: true,
          timeout: 5000,
          maximumAge: 0,
        });
      }
      else
      {
        alert('error')
      }
    },
    initMap(position){
      AMapLoader
          .load({
        key:"99df1adfafd916e84e7b953d75c626d7",             // 申请好的Web端开发者Key，首次调用 load 时必填
        version:"2.0",      // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
        plugins:['AMap.MouseTool'],       // 需要使用的的插件列表，如比例尺'AMap.Scale'等
      })
          .then((AMap)=>{
              map = new AMap.Map("container",//设置地图容器id
                {
                  // viewMode:"3D",    //是否为3D地图模式
                  zoom:15,           //初始化地图级别
                  center:position, //初始化地图中心点位置
                });
              this.map=map
            let img=require("/public/direction.svg")
            this.currentPositionOpt.icon=new AMap["Icon"]({
              image: img,
              imageSize:[36,36]
            })
            })
          .catch(e=>{
            console.log(e);
          })
    },
    /**
     * 获取当前定位
     */
    getLocationByJs(){
      if (navigator.geolocation){
        navigator.geolocation.getCurrentPosition(this.navigatorPositionSuccess,(e)=>{
          this.warningMessage("定位失败")
        },{
          enableHighAccuracy: true,
          timeout: 5000,
          maximumAge: 0,
        });
      }
      else
      {
        alert('error')
      }
    },
    /**
     * 开启位置跟踪
     */
    startPath() {
      console.log(TrackData)
      if (navigator.geolocation) {
        //id为undefined，在数据库创建一个路径，并获取id
        if(typeof(this.uploadDate.id)==="undefined"){
          const myConfig = this.getConfig();
          console.log(myConfig)
          reqPostTrack(myConfig).then(result=>{
            if (requestIsSuccess(result)) {
              this.uploadDate.id = requestGetData(result).id
              this.uploadDate.dataId = requestGetData(result).dataId
              this.currentPositionOpt.extData.id=this.uploadDate.dataId
              debugger
            } else {
              this.warningMessage("无法联网，请重试");
            }
          })

        }
        //开启位置上传的定时器
        this.uploadDate.uploadInterval = setInterval(this.uploadPositionsInterval, uploadPositionsTime)
        //开启位置追踪
        if(!this.simulationData.startPositionSimulation)
          this.uploadDate.navigatorWatch = navigator.geolocation.watchPosition(
              this.navigatorPositionSuccess,
              (e) => {}, {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0,
          });
        else{
          this.simulationData.positionSimulationInterval = setInterval(()=>{
            var startIndex = this.uploadDate.positions.length
            this.navigatorPositionSuccess({
              coords:{
                longitude:this.simulationData.simulationPositions[startIndex][0],
                latitude:this.simulationData.simulationPositions[startIndex][1],
                speed:5,
                accuracy:1
              },
            })
          },uploadPositionsTime/10)
          successMessage("开启定位模拟")
        }
        this.uploadDate.isStartWatch = true;
        navigator.wakeLock.request('screen').then(result => {
          this.uploadDate.wakeLock = result;
          this.successMessage("保存屏幕常亮")
        })
      }
      else {
        this.warningMessage("navigator.geolocation not found")
      }
    },
    /**
     * 结束位置跟踪
     */
    stopPath(){
      //没有暂停定位，暂停定位
      if(this.uploadDate.isStartWatch)
        this.pausePath();
      this.pathTime='';
      this.uploadDate.positions=[];
      this.currentPositionOpt.position=void 0
      this.uploadDate.id=void 0;

      this.currentPositionMapData.setMap()
      this.map.getAllOverlays().forEach(item=>{
        item.setOptions({
          ...item.getOptions(),
          "strokeColor": "#a7d714"
        })
      })
    },
    /**
     * 暂停位置定位
     */
    pausePath(){
      this.speed=0
      this.uploadPositionsInterval();
      if(!this.simulationData.startPositionSimulation) {
        navigator.geolocation.clearWatch(this.uploadDate.navigatorWatch)
      }
      else {
        clearInterval(this.simulationData.positionSimulationInterval)
      }
      clearInterval(this.uploadDate.uploadInterval);
      this.uploadDate.isStartWatch=false;
      this.uploadDate.wakeLock.release().then(() => this.uploadDate.wakeLock = null);
    },
    /**
     * 返回路径的MyMap的设置
     * @param start 需要上传的坐标点起始index
     * @param end 需要上传的坐标的终止index
     * @returns {{data: {path: *[], fillOpacity: number, extData: {speed: *[]}, borderWeight: number, strokeColor: string}, name: string, id: *, type: string, coordsys: string}}
     */
    getConfig(start=0,end=this.uploadDate.positions.length-1){
      const config = {
        mapData:new MapData({
          id:this.uploadDate.id,
          type:MyMapOpt.MapType.Track,
          coordsys:MyMapOpt.MapCoordSys.GPS,
          name:"位置"+Date.now(),
        }),
        track:new Track({
          id:this.uploadDate.dataId,
          path:this.uploadDate.positions.slice(start,end),
          ext_data:{},
          speed:[]
        })
      }
      return config
    },
    export2JSON(){
      const myTravel = new MyMap(this.getConfig());
      myTravel.getJSON();
    },
    addPosition2Data(position){
      this.uploadDate.positions.push(position)
    },

    async navigatorPositionSuccess(position) {
      // speedFlag=1速度低于1，不计入待上传点；accuracy=10，精度高于10m不计入待上传点
      const speedFlag=1,accuracyFlag=10
      const {longitude, latitude,accuracy} = position.coords
      this.accuracy=parseFloat(accuracy.toFixed(2))
      let tempSpeed = position.coords.speed * 3.6.toFixed(2)
      this.speed = tempSpeed
      if(this.accuracy>accuracyFlag||this.speed<speedFlag){
        return
      }
      let positionConverted
      if(this.mapCoordSys===MyMapOpt.MapCoordSys.CJ02)
        positionConverted = convert_gps84_To_Gcj02([longitude, latitude]);
      else
        positionConverted=[longitude,latitude]
      if (this.uploadDate.followPosition) {
        this.map.setCenter(positionConverted)
      }

      //更新经过的线和方向
      if(!(typeof(this.currentPositionOpt.position)==="undefined")) {
        //非第一次添加数据，添加线段，避免[0,0]
        var currentPolyline = {
          path: [this.currentPositionOpt.position, positionConverted],
          strokeColor:getColorBySpeed(tempSpeed)
        }
        const myPolyline = new AMap.Polyline(currentPolyline)
        this.map.add(myPolyline)



        //如果速度慢，不更新方向
        // if(true) {
        if(tempSpeed>2) {
          const angle = this.calAngle(this.currentPositionOpt.position[0], this.currentPositionOpt.position[1], positionConverted[0], positionConverted[1])
          this.currentPositionOpt.rotate = angle - 45
        }

        this.currentPositionMapData.setOptions({
          position:positionConverted,
          rotate:this.currentPositionOpt.rotate
        })
      }else{
        this.currentPositionOpt.position=positionConverted
        this.currentPositionMapData=new AMap.Marker(this.currentPositionOpt)
        this.map.add(this.currentPositionMapData)
      }
      this.currentPositionOpt.position.splice(0,2,positionConverted[0],positionConverted[1])

      if (this.uploadDate.isStartWatch) {
        //添加数据
        this.uploadDate.positions.push([longitude, latitude])
        this.uploadDate.speeds.push({
          index: this.uploadDate.positions.length-1,
          speed: tempSpeed,
          time: Date.now()
        })
        if(tempSpeed>1){ //todo是否可以删除
          this.positionsExtDataSpeed.push({
            index: this.uploadDate.positions.length - 1,
            speed: tempSpeed,
            time: Date.now()
          })
        }
      }
    },
    calAngle(cx, cy, x, y) {
      const radian = getCosBy2pt(x, y, cx, cy);
      let angle = Math.acos(radian) * 180 / Math.PI;

      if (x < cx) angle = -angle;
      return angle;

      // 计算 点1指点2形成 的向量
      function getCosBy2pt(x, y, cx, cy) {
        let a = [x - cx, y - cy];
        let b = [0, 1];
        return calCos(a, b);
      }
      function calCos(a, b) {
        // 点积
        let dotProduct = a[0] * b[0] + a[1] * b[1];
        let d = Math.sqrt(a[0] * a[0] + a[1] * a[1]) * Math.sqrt(b[0] * b[0] + b[1] * b[1]);
        return dotProduct/d;
      }
},

    async uploadPositionsInterval() {
      // 判断是否有新的点更新：ture->有新的点需要更新
      if (this.uploadDate.startIndexWithoutUpload < this.uploadDate.positions.length) {
        // 判断是否有id，ture：通过id上传点坐标
        if (this.uploadDate.id) {
          const startIndex = this.uploadDate.startIndexWithoutUpload;
          const endIndex = this.uploadDate.positions.length-1;
          const data = {
            id:this.uploadDate.dataId,
            path:this.uploadDate.positions.slice(startIndex,endIndex),
            speed:this.uploadDate.speeds.slice(startIndex,endIndex)
          };
          console.log("upload",startIndex,endIndex)
          const result = await reqPutAddPath(data)
          if (requestIsSuccess(result)) {
            this.uploadDate.startIndexWithoutUpload = endIndex+1
          }
        }
      }
    }
  },
  mounted() {

  },
  beforeDestroy() {
    this.stopPath()
  },
  data(){
    return{
      uploadDate:{
        //保存的位置
        positions:[],
        //速度记录
        speeds:[],
        //地理位置跟踪时的ID
        navigatorWatch:'',
        //是否跟踪位置
        followPosition:true,
        //是否开启定位记录
        isStartWatch:false,
        // 未上传的点的index
        startIndexWithoutUpload:0,
        // 定时上传flag
        uploadInterval:void 0,
        //屏幕休眠
        wakeLock:void 0,
        // 在mapdata中的id
        id:void 0,
        dataId:void 0,
      },
      //保存数据记录
      positionsExtDataSpeed:[],
      speed:0,
      //当前定位精度
      accuracy:0,
      //地图当前位置样式及属性
      currentPositionOpt:{
        position:void 0,
        extData: {
          name:currentPositionName,
          id:void 0
        },
        icon : void 0,
        offset:[-18,-18],
        rotate:-45,
      },
      map:void 0,
      mapCoordSys:MyMapOpt.MapCoordSys.CJ02,
      canChangeLayer:true,
      //当前点的地图要素
      currentPositionMapData:void 0,
      simulationData:{
        //开启位置模拟 false表示不开启位置模拟；true开启位置模拟，自动添加坐标点
        startPositionSimulation:false,
        //模拟定位定时器
        positionSimulationInterval:void 0,
        //模拟位置坐标：
        simulationPositions:simulationPositions
      },

    }
  },
}
</script>

<style scoped>
#map{

  width: 100%;
  position: relative;
  height: 400px;
}
#container{
  height: 100%;
  position: relative;
}
.mapinfo{
  background-color: skyblue;
  position: absolute;
  right: 0;
  bottom: 0;
  display: inline-block;
}
.mapinfo div{
  text-align: center;
}
.speedSetting{
  display: inline-block;
  width: 180px;
  float:left;
}
.info{
  margin: 5px;
}
</style>